package org.study.local.boot.controller;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.MultipartConfig;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.study.local.boot.config.LocalFileProperties;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.*;

/**
 * 作用描述
 *
 * @author doveylovey
 * @version v1.0.0
 * @email 1135782208@qq.com
 * @date 2025年08月28日
 */
@Slf4j
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@WebServlet("/servlet/upload")
@MultipartConfig(
        fileSizeThreshold = 1 * 1024 * 1024,// 1MB
        maxFileSize = 10 * 1024 * 1024,     // 10MB
        maxRequestSize = 50 * 1024 * 1024   // 50MB
)
public class FileUploadHttpServlet extends HttpServlet {
    private final LocalFileProperties localFileProperties;
    private final static List<String> FILE_TYPE = Arrays.asList(".jpg", ".png", ".gif");
    private final static Long FILE_MAX_SIZE = 4 * 1024 * 1024L;

    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 设置编码
        request.setCharacterEncoding(StandardCharsets.UTF_8.name());
        // 从请求对象中获取文件上传对象Part
        Part filePart = request.getPart("file");
        long partSize = filePart.getSize();
        String fileName = filePart.getSubmittedFileName();
        String fileType = fileName.substring(fileName.lastIndexOf("."));
        // 文件相关信息校验，如类型、大小等
        log.info("文件名称：{}", fileName);
        log.info("文件类型：{}", fileType);
        log.info("文件大小：{}", FileUtil.readableFileSize(partSize));
        if (partSize > FILE_MAX_SIZE) {
            this.writeResp(response, "文件大小超过4M");
            return;
        }
        if (!FILE_TYPE.contains(fileType.toLowerCase())) {
            this.writeResp(response, "文件类型错误");
            return;
        }
        String filePath = localFileProperties.getUploadFolder() + fileName;
        File uploadPath = new File(localFileProperties.getUploadFolder() + DateUtil.format(LocalDateTime.now(), DatePattern.PURE_DATE_PATTERN));
        if (!uploadPath.exists()) {
            uploadPath.mkdirs();
        }
        // 拼接文件保存路径
        String savePath = uploadPath.getAbsolutePath() + File.separator + IdUtil.getSnowflakeNextId() + fileType;
        log.info("保存路径：{}", savePath);
        // 方式一
        /*File file = new File(savePath);
        filePart.write(file.getAbsolutePath());*/
        // 方式二
        try (BufferedInputStream bis = new BufferedInputStream(filePart.getInputStream());
             BufferedOutputStream bos = new BufferedOutputStream((new FileOutputStream(savePath)))) {
            int len;
            byte[] buffer = new byte[1024];
            while ((len = bis.read(buffer)) != -1) {
                bos.write(buffer, 0, len);
            }
            bos.flush();
        } catch (Exception ex) {
            this.writeResp(response, "上传失败");
            return;
        }
        this.writeResp(response, "上传完成");
    }

    private void writeResp(HttpServletResponse response, String msg) throws IOException {
        response.setCharacterEncoding(StandardCharsets.UTF_8.name());
        response.setContentType("text/html; charset=utf-8");
        try (PrintWriter printWriter = response.getWriter()) {
            Map<Object, Object> retMap = new LinkedHashMap<>() {{
                this.put("code", "00000");
                this.put("datetime", DateUtil.now());
                this.put("msg", msg);
            }};
            printWriter.println(retMap);
        }
    }
}
